const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const { Sequelize } = require('sequelize');
const sequelize = require('../config/database');
const { format } = require('date-fns');

// 备份目录路径
const BACKUP_DIR = path.join(__dirname, '../backups');

// 确保备份目录存在
if (!fs.existsSync(BACKUP_DIR)) {
  fs.mkdirSync(BACKUP_DIR, { recursive: true });
}

// 数据库备份
exports.backupDatabase = async (req, res) => {
  try {
    // 仅管理员可执行
    if (req.user.role !== 'admin') {
      return res.status(403).json({
        success: false,
        message: '权限不足，仅管理员可执行备份操作'
      });
    }

    // 生成备份文件名 (包含时间戳)
    const timestamp = format(new Date(), 'yyyyMMddHHmmss');
    const backupFileName = `backup_${timestamp}.sql`;
    const backupFilePath = path.join(BACKUP_DIR, backupFileName);

    // 获取数据库配置
    const dbConfig = sequelize.config;

    // 构建备份命令 (SQL Server)
    const backupCommand = `sqlcmd -S ${dbConfig.host},${dbConfig.port} -U ${dbConfig.username} -P ${dbConfig.password} -d ${dbConfig.database} -Q "BACKUP DATABASE ${dbConfig.database} TO DISK='${backupFilePath}'"`;

    // 执行备份命令
    exec(backupCommand, (error, stdout, stderr) => {
      if (error) {
        console.error('数据库备份失败:', error);
        return res.status(500).json({
          success: false,
          message: '数据库备份失败',
          error: error.message,
          stderr: stderr
        });
      }

      // 记录备份日志
      const logEntry = `[${new Date().toISOString()}] 备份成功: ${backupFileName}\n`;
      fs.appendFileSync(path.join(BACKUP_DIR, 'backup_log.txt'), logEntry);

      return res.status(200).json({
        success: true,
        message: '数据库备份成功',
        data: {
          backupFileName,
          backupFilePath,
          size: fs.statSync(backupFilePath).size
        }
      });
    });
  } catch (error) {
    console.error('备份控制器错误:', error);
    return res.status(500).json({
      success: false,
      message: '服务器错误，备份操作失败',
      error: error.message
    });
  }
};

// 恢复数据库
exports.restoreDatabase = async (req, res) => {
  try {
    // 仅管理员可执行
    if (req.user.role !== 'admin') {
      return res.status(403).json({
        success: false,
        message: '权限不足，仅管理员可执行恢复操作'
      });
    }

    const { backupFileName } = req.body;
    if (!backupFileName) {
      return res.status(400).json({
        success: false,
        message: '请提供备份文件名'
      });
    }

    const backupFilePath = path.join(BACKUP_DIR, backupFileName);

    // 检查备份文件是否存在
    if (!fs.existsSync(backupFilePath)) {
      return res.status(404).json({
        success: false,
        message: '备份文件不存在'
      });
    }

    // 获取数据库配置
    const dbConfig = sequelize.config;

    // 构建恢复命令 (SQL Server)
    const restoreCommand = `sqlcmd -S ${dbConfig.host},${dbConfig.port} -U ${dbConfig.username} -P ${dbConfig.password} -d master -Q "ALTER DATABASE ${dbConfig.database} SET SINGLE_USER WITH ROLLBACK IMMEDIATE; RESTORE DATABASE ${dbConfig.database} FROM DISK='${backupFilePath}' WITH REPLACE; ALTER DATABASE ${dbConfig.database} SET MULTI_USER"`;

    // 执行恢复命令
    exec(restoreCommand, (error, stdout, stderr) => {
      if (error) {
        console.error('数据库恢复失败:', error);
        return res.status(500).json({
          success: false,
          message: '数据库恢复失败',
          error: error.message,
          stderr: stderr
        });
      }

      // 记录恢复日志
      const logEntry = `[${new Date().toISOString()}] 恢复成功: ${backupFileName}\n`;
      fs.appendFileSync(path.join(BACKUP_DIR, 'restore_log.txt'), logEntry);

      return res.status(200).json({
        success: true,
        message: '数据库恢复成功',
        data: { backupFileName }
      });
    });
  } catch (error) {
    console.error('恢复控制器错误:', error);
    return res.status(500).json({
      success: false,
      message: '服务器错误，恢复操作失败',
      error: error.message
    });
  }
};

// 获取备份文件列表
exports.getBackupFiles = async (req, res) => {
  try {
    // 仅管理员可访问
    if (req.user.role !== 'admin') {
      return res.status(403).json({
        success: false,
        message: '权限不足，仅管理员可查看备份文件'
      });
    }

    // 读取备份目录下的所有.sql文件
    const files = fs.readdirSync(BACKUP_DIR)
      .filter(file => file.endsWith('.sql'))
      .map(file => {
        const stats = fs.statSync(path.join(BACKUP_DIR, file));
        return {
          fileName: file,
          size: stats.size,
          createdAt: stats.birthtime,
          modifiedAt: stats.mtime
        };
      })
      .sort((a, b) => b.createdAt - a.createdAt); // 按创建时间降序排序

    return res.status(200).json({
      success: true,
      total: files.length,
      data: files
    });
  } catch (error) {
    console.error('获取备份文件列表失败:', error);
    return res.status(500).json({
      success: false,
      message: '服务器错误，获取备份文件列表失败',
      error: error.message
    });
  }
};

// 删除备份文件
exports.deleteBackupFile = async (req, res) => {
  try {
    // 仅管理员可执行
    if (req.user.role !== 'admin') {
      return res.status(403).json({
        success: false,
        message: '权限不足，仅管理员可删除备份文件'
      });
    }

    const { fileName } = req.params;
    if (!fileName) {
      return res.status(400).json({
        success: false,
        message: '请提供备份文件名'
      });
    }

    const filePath = path.join(BACKUP_DIR, fileName);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({
        success: false,
        message: '备份文件不存在'
      });
    }

    // 删除文件
    fs.unlinkSync(filePath);

    // 记录删除日志
    const logEntry = `[${new Date().toISOString()}] 删除备份: ${fileName}\n`;
    fs.appendFileSync(path.join(BACKUP_DIR, 'backup_log.txt'), logEntry);

    return res.status(200).json({
      success: true,
      message: '备份文件删除成功',
      data: { fileName }
    });
  } catch (error) {
    console.error('删除备份文件失败:', error);
    return res.status(500).json({
      success: false,
      message: '服务器错误，删除备份文件失败',
      error: error.message
    });
  }
};